const http = {
    get: (url) => {
        let options = {
            url: url,
            type: 'get',
            contentType: 'application/x-www-form-urlencoded;utf-8'
        }
        if (!options.url) {
            throw "url is not defined"
        }
        return http.request(options)
    },
    post: (url, data) => {
        let options = {
            url: url,
            data: data,
            type: 'post'
        }
        if (!options.url) {
            throw "url is not defined"
        }
        return http.request(options)
    },
    fileUpload: (url, file, data) => {
        let options = {
            url: url,
            data: data,
            type: 'post'
        }
        let form = new FormData()
        form.append('file', file)
        if (!options.url) {
            throw "url is not defined"
        }
        if (options.data) {
            Object.keys(options.data).map(k => {
                form.append(k, options.data[k])
            })
        }
        options.data = form
        return http.request(options)
    },
    /**
     * {url, type, contentType, timeout[number/function], async, data, header, beforeSend, success, error, abort, end}
     */
    request: (options) => {
        return new Promise((resolve, reject) => {
            options = Object.assign({
                timeout: 18e4, 
                async: false, 
                type: 'post',
                contentType: 'application/json'
            }, options)
            let xhr = new XMLHttpRequest()
            let sender = options.data
            if (options.async === false) {
                xhr.timeout = 0
            }
            if (options.url.toLowerCase() === 'get') {
                options.url += (options.url.indexOf('?') > -1? '': '?') + formRequestData(options.data)
            } else {
                try {
                    sender = JSON.stringify(sender || {})
                } catch(e) {}
            }
            xhr.open(options.type, options.url, options.async)
            xhr.setRequestHeader('Content-Type', options.contentType)
            if (options.header) {
                Object.keys(options.header).map(h => {
                    xhr.setRequestHeader(h, options.header[h])
                })
            }
            if (options.beforeSend) {
                typeof options.beforeSend === 'function' && options.beforeSend(xhr)
            }
            xhr.onload = (result) => {
                if (result && result.target.responseText) {
                    let data = result.target.responseText
                    if (result.target.status === 200) {
                        try {
                            data = JSON.parse(data)
                        } catch(e) {console.warn(e)}
                        if (options.success) {
                            typeof options.success === 'function' && options.success(data)
                        }
                        resolve(data)
                    } else {
                        console.warn(data)
                        if (options.error) {
                            typeof options.error === 'function' && options.error(data)
                        }
                        reject(data)
                    }
                }
            },
            xhr.ontimeout = (e) => {
                typeof options.timeout === 'function' && options.timeout(e)
                xhr.abort()
                console.log('request timeout.')
                reject(e)
            }
            xhr.onabort = (e) => {
                typeof options.abort == "function" && options.abort(e)
                console.log('request abort.')
            }
            xhr.onloadend = (e) => {
                typeof options.end == "function" && options.end(e)
            }
            xhr.send(sender)
        })
    },
    formRequestData: (dataJson) => {
        let senderStr = null
        if (dataJson) {
            Object.keys(dataJson).map((k, i) => {
                senderStr += (i!==0? '&': '') + k + '=' + dataJson[k]
            })
        }
        return senderStr
    }
}

export default {
    get: http.get,
    post: http.post,
    request: http.request,
    fileUpload: http.fileUpload
}